// Copyright (c) 2023 Presto Labs Pte. Ltd.
// Author: fengyang

#pragma once

#include "string_view"
#include "coin2/exchange/base/feed_util/trading_data.h"

namespace coin2::exchange::base::feed::replay {

// only support snapshot as the most of cases are light_bbo and move2bp
enum class TradingDataEventType {
  Unknow,
  Clear,
  Snapshot,
  Add,
  Freeze,
  Remove,
};

template<typename T>
struct TradingDataEvent {
  TradingDataEventType type;
  int64_t timestamp;
  fastfeed::proto::TradingDataInterval interval;
  std::vector<T> data;
};

class TradingDataEventBuilder {
 public:
  TradingDataEventBuilder() {
  }

  template<typename T>
  TradingDataEvent<T> ToEvent(std::string_view native_symbol, const TradingData<T>& trading_data) {
    auto interval = trading_data.Interval();
    auto k = std::make_pair(std::string(native_symbol), interval);
    auto ts_iter = last_timestamp_.find(k);
    int64_t last_timestamp = 0;
    if (ts_iter != last_timestamp_.end()) {
      last_timestamp = ts_iter->second;
    }

    TradingDataEvent<T> event;
    event.type = TradingDataEventType::Add;
    event.interval = interval;

    typename TradingData<T>::Iterator iter = trading_data.Begin();
    int capacity = 0;
    for ( ; iter != trading_data.End(); iter++) {
      if (iter->timestamp <= last_timestamp) break;

      capacity++;
    }

    if (capacity > 0) {
      last_timestamp_[k] = trading_data.Begin()->timestamp;
    }

    event.data.resize(capacity);
    for (int idx =0; idx < capacity; idx++) {
      event.data[idx] = *(trading_data.Get(capacity - idx -1).value());
    }

    return event;
  };

 private:
  std::map<std::pair<std::string, fastfeed::proto::TradingDataInterval>, int64_t> last_timestamp_;
};

}  // namespace coin2::exchange::base::feed::replay
